package org.lex.swing.widgets;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;

import org.lex.swing.Option;
import org.lex.swing.OptionType;


public class OptionDialogUI extends EnhancedDialog {
	private JPanel optionPane = null;
	private JPanel messagePane = null;
	private JLabel iconLabel = null;
	private JLabel messageLabel = null;
	private JPanel buttonsPane = null;
	private JButton[] buttons = null;
	// ====================================
	private Option option = Option.CANCEL;
	private Action[] actions = null;

	private OptionType optionType = OptionType.getDefaultOptionTyle();

	public OptionDialogUI(Window owner) {
		super(owner);
		this.initialize();
		this.pack();
	}

	public OptionDialogUI(Window owner, String title, Icon icon, String message, OptionType optionType, Action... actions) {
		super(owner);
		this.setTitle(title);
		this.setIcon(icon);
		this.setMessage(message);
		this.optionType = optionType;
		this.actions = actions;

		this.initialize();
	}

	public Option getOption() {
		return this.option;
	}

	public void setIcon(Icon icon) {
		this.getIconLabel().setIcon(icon);
	}

	public void setMessage(String message) {
		this.getMessageLabel().setText(message);
	}

	@Override
	public void cancel() {
		option = Option.CANCEL;
		dispose();
	}

	// =======================
	private void initialize() {
		this.setSize(300, 200);
		this.setModal(true);
		this.setContentPane(getOptionPane());
	}

	private JPanel getOptionPane() {
		if (optionPane == null) {
			optionPane = new JPanel();
			optionPane.setLayout(new GridBagLayout());

			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.BOTH;
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.gridy = 2;
			gridBagConstraints1.ipadx = 0;
			gridBagConstraints1.ipady = 0;
			gridBagConstraints1.weightx = 10.0;
			gridBagConstraints1.weighty = 10.0;
			gridBagConstraints1.insets = new Insets(9, 12, 11, 11);
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.ipadx = 0;
			gridBagConstraints.weightx = 10.0;
			gridBagConstraints.insets = new Insets(6, 12, 0, 11);
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 0;
			gridBagConstraints11.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints11.weightx = 10.0;
			gridBagConstraints11.insets = new Insets(12, 10, 0, 9);
			gridBagConstraints11.gridy = 1;

			optionPane.add(getMessagePane(), gridBagConstraints);
			optionPane.add(getButtonsPane(), gridBagConstraints1);
			optionPane.add(new JSeparator(), gridBagConstraints11);
		}
		return optionPane;
	}

	private JPanel getMessagePane() {
		if (messagePane == null) {
			BorderLayout borderLayout = new BorderLayout();
			borderLayout.setHgap(11);
			messagePane = new JPanel();
			messagePane.setLayout(borderLayout);
			messagePane.add(this.getIconLabel(), BorderLayout.WEST);
			messagePane.add(this.getMessageLabel(), BorderLayout.CENTER);
		}
		return messagePane;
	}

	private JLabel getIconLabel() {
		if (null == iconLabel) {
			iconLabel = new JLabel();
		}
		return iconLabel;
	}

	private JLabel getMessageLabel() {
		if (null == messageLabel) {
			messageLabel = new JLabel();
		}
		return messageLabel;
	}

	private JPanel getButtonsPane() {
		if (buttonsPane == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(this.optionType.getOptionCount());
			gridLayout.setVgap(2);
			gridLayout.setColumns(1);
			buttonsPane = new JPanel();
			buttonsPane.setLayout(gridLayout);

			for (JButton button : this.getButtons())
				buttonsPane.add(button, null);
		}
		return buttonsPane;
	}

	private JButton[] getButtons() {
		if (null == this.buttons) {
			this.buttons = new JButton[this.optionType.getOptionCount()];
			String[] names = this.optionType.getOptionDiaplayNames();
			ButtonsActionHandler h = new ButtonsActionHandler();
			if (null == this.actions)
				this.actions = new Action[0];
			StringBuilder buffer = new StringBuilder();
			for (int i = 0, j = 0; i < buttons.length; i++) {
				JButton b = new RolloverButton();
				String text = names[i];
				if (j < actions.length) {
					Action a = actions[j++];
					if (null != a) {
						b.setAction(a);
						buffer.setLength(0);
						buffer.append("<html><font size=4><b>");
						buffer.append(a.getValue(Action.NAME));
						buffer.append("</b></font><br>");
						buffer.append(a.getValue(Action.SHORT_DESCRIPTION));
						buffer.append("</html>");
						text = buffer.toString();
					}
				}
				b.setText(text);
				b.setHorizontalAlignment(SwingConstants.LEADING);
				b.setActionCommand(Integer.toString(i));
				b.addActionListener(h);
				buttons[i] = b;
			}
		}
		return this.buttons;
	}

	class ButtonsActionHandler implements ActionListener {
		Option[] options = optionType.getOptions();

		public void actionPerformed(ActionEvent e) {
			String ac = e.getActionCommand();
			if (null == ac)
				return;
			option = options[Integer.parseInt(ac)];
			dispose();
		}
	}
}
